home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / music / ptsupp.lha / PT Support archive / Sources / SoundFX.S < prev   
Text File  |  1996-01-30  |  15KB  |  570 lines

  1.  
  2. SFX__BuffSize    =    286            ; Must be an even number!
  3. SFX__FastMode    =    0
  4. SFX__Debug    =    1
  5. SFX__Mode    =    1
  6.  
  7.         jmp    Go
  8.  
  9. ; Your samples. Locate in fast if possible!
  10.  
  11.     INCDIR    "!Sources:Productions/PTSupp/"
  12.  
  13. Sample1    INCBIN    SAMPLE1
  14.     dcb.b    64,0
  15. Sample1End
  16.  
  17. Sample2    INCBIN    SAMPLE2
  18.     dcb.b    416,0
  19. Sample2End
  20.  
  21. Go        move.w    #248,d0
  22.         bsr.w    SFX_Init        ; Initialize with fairly low
  23.                         ; rate. (This makes us use
  24.                         ; samples with low frequencies,
  25.                         ; which again saves memory!)
  26.         beq.s    .Quit
  27.  
  28.         moveq.l    #0,d0
  29.         lea.l    Sample1,a0
  30.         lea.l    Sample1End,a1
  31.         bsr.w    SFX_StartSound        ; Start sample 1
  32.  
  33.         moveq.l    #1,d0
  34.         lea.l    Sample2,a0
  35.         lea.l    Sample2End,a1
  36.         bsr.w    SFX_StartSound        ; Start sample 2
  37.  
  38. .a        cmp.b    #$ff,$dff006
  39.         bne.s    .a
  40. .b        cmp.b    #$ff,$dff006
  41.         beq.s    .b
  42.  
  43.         btst    #6,$bfe001        ; Wait for mouse
  44.         bne.s    .a
  45.  
  46. .Quit        bsr.w    SFX_End            ; End
  47.  
  48.         moveq.l    #0,d0            ; Successful exit
  49.         rts
  50.  
  51. ;------------------------------------------------------------------------------
  52. ;
  53. ;    $VER: SoundFX v1.2 sound replay - by Håvard "Howard" Pedersen
  54. ;    © 1994-96 Mental Diseases
  55. ;
  56. ;    A simple program for handling the replay of multiple soundeffects
  57. ;    through a single audio channel.
  58. ;
  59. ;    I cannot be held responsible for any damage caused directly or in-
  60. ;    directly by this code. Still, every released version is thouroughly
  61. ;    tested with Mungwall and Enforcer, official Commodore debugging tools.
  62. ;    These programs traps writes to unallocated ram and reads/writes to/from
  63. ;    non-ram memory areas, which should cover most bugs.
  64. ;
  65. ;    HISTORY:
  66. ;
  67. ;v1.0    Based on an article in AM/FM #11 by Teijo Kinuunen. Simple thing with
  68. ;    preset playback rate. Soundeffects length has to be a multiple of
  69. ;    SFX__BuffSize.
  70. ;
  71. ;v1.1    Upvamped version.
  72. ;    * Selectable playback rate. (No big deal)
  73. ;    * Mastervolume.
  74. ;
  75. ;v1.2    Threw the original mixing scheme out.
  76. ;    * Fixed a bug where the interrupt sometimes didn't fill the entire
  77. ;      output-buffer. (Clicks and distorted sound could occur!)
  78. ;    * The end-of-sound detection was a bit buggy. Fixed.
  79. ;    * Earlier there was some problems with the sound not always appearing
  80. ;      when running SoundFX for the first time. This _seems_ to be fixed.
  81. ;    * Included fast mode. (Max 246/248 in playback rate!)
  82. ;    * Added SFX_StopSound().
  83. ;    * Optimized mixing a lot.
  84. ;    * SoundFX did not stop when errors occured. Now errors are properly
  85. ;      signalled.
  86. ;    * Did some alterations to make the source more portable. (Stopped using
  87. ;      includes and my personal macros.)
  88. ;    * Uses Disable()/Enable() instead of some bogus macros to disable
  89. ;      interrupts.
  90. ;    * Added non-interrupt mode, to make it possible to mix the channels
  91. ;      within a vertical-blank interrupt.
  92. ;
  93. ;    TODO:
  94. ;
  95. ;* Expand to 2 channels/4 voices. (optional)
  96. ;
  97. ;------------------------------------------------------------------------------
  98. ;
  99. ;    CONSTANTS:
  100. ;
  101. ;Constant:    SFX__BuffSize(INTEGER)
  102. ;Purpose:    Specifies the size of SoundFXs output buffer. The number should
  103. ;        be even. A large value causes less overhead by the interrupt
  104. ;        code but uses more memory for the buffers.
  105. ;
  106. ;Constant:    SFX__FastMode(BOOL)
  107. ;Purpose:    If set to non-zero, the fastmode will be enabled. The fastmode
  108. ;        provides faster mixing but is only capable of playing samples
  109. ;        at half the normal rates. Please also note that the sounddata
  110. ;        does not need to be halved when using the fastmode. This mixing
  111. ;        mode may produce high-frequency tones which may both distort
  112. ;        the sound and destroy loudspeakers! To get rid of this extra-
  113. ;        feature, enable the audio filter. :)
  114. ;
  115. ;Constant:    SFX__Debug(BOOL)
  116. ;Purpose:    If set to true, colors will be used to display CPU usage for
  117. ;        mixing loop.
  118. ;
  119. ;Constant:    SFX__Mode(BOOL)
  120. ;Purpose:    Selects the mode for SoundFX to run in. Modes are:
  121. ;        0 - User vertical blank. SoundFX will be set up for vertical
  122. ;            blank operation, but relies on the user to call
  123. ;            SFX_VBLHandle() each vertical blank.
  124. ;        1 - OS AudioInterrupt. SoundFX installs the interrupt itself
  125. ;            using the operating system.
  126. ;        Vertical blank modes needs you to carefully pick the buffersize
  127. ;        so that it's just about finished playing in one frame.
  128. ;
  129. ;    PUBLIC FUNCTIONS:
  130. ;
  131. ;Function:    SFX_Init(Rate)(D0)
  132. ;Purpose:    Initalize the routine and install audio-interrupt. Remember
  133. ;        that when the fastmode is enabled the actual sample playback
  134. ;        frequence will be half of what you state. Maximum values are
  135. ;        123 for PAL and 124 for NTSC. Remember to double these figures
  136. ;        when using the fastmode.
  137. ;
  138. ;Function:    SFX_End()
  139. ;Purpose:    Remove our audio interrupt and free any allocated resources.
  140. ;
  141. ;Function:    SFX_StartSound(Partition,Wave,Waveend)(D0,A0,A1)
  142. ;Purpose:    Start playing the selected sound. The sounddata should be
  143. ;        halved if the fastmode is disabled.
  144. ;
  145. ;Function:    SFX_StopSound(Partition)(D0)
  146. ;Purpose:    Stops the current sound.
  147. ;
  148. ;Function:    SFX_SetVolume(Volume.w (0-64))(D0)
  149. ;Purpose:    Alters the playback volume. Use for fading.
  150. ;
  151. ;    PRIVATE FUNCTIONS:
  152. ;
  153. ;Function:    SFX_VBLInit()
  154. ;Purpose:    Initializes SoundFX for use without using the audio interrupt.
  155. ;
  156. ;Function:    SFX_VBLEnd()
  157. ;Purpose:    Closes down SoundFX when audio interrupt hasn't been used.
  158. ;
  159. ;Function:    SFX_VBLHandle()
  160. ;        Does the actuall stuff when SoundFX is run in VBL-mode.
  161. ;
  162. ;Function:    SFX_AudIntInit()
  163. ;Purpose:    Initializes the audio interrupt handler.
  164. ;
  165. ;Function:    SFX_AudIntEnd()
  166. ;Purpose:    Closes down the audio interrupt handler.
  167. ;
  168. ;Function:    SFX_AudInt()
  169. ;Purpose:    This is the interrupt-handler for SoundFX when running in audio
  170. ;        interrupt mode.
  171. ;
  172. ;Function:    SFX_DoMix()
  173. ;Purpose:    Does actual mixing.
  174. ;
  175. ;------------------------------------------------------------------------------
  176.  
  177. ; Set all undefined constants to default values. If you dont't like 'em, feel
  178. ; free to change, though you'll have to do it all over for each new version.
  179.  
  180.     ifnd SFX__BuffSize
  181. SFX__BuffSize    =    1024            ; 16-131072
  182.     endc
  183.  
  184.     ifnd SFX__FastMode
  185. SFX__FastMode    =    0            ; BOOL
  186.     endc
  187.  
  188.     ifnd SFX__Debug
  189. SFX__Debug    =    0            ; BOOL
  190.     endc
  191.  
  192.     ifnd SFX__Mode
  193. SFX__Mode    =    1            ; BOOL
  194.     endc
  195.  
  196.     rsreset    ; Voice data
  197. vd_StartPtr    rs.l    1            ; Start of data, CHIP
  198. vd_EndPtr    rs.l    1            ; End of data, CHIP
  199. vd_Active    rs.l    1
  200. vd_sizeof    rs.b    0
  201.  
  202. SFX_WAITDMA    macro
  203.         move.w    $dff006,d1
  204.         moveq.l    #80-1,d0
  205. .DMALoop1    cmp.w    $dff006,d1
  206.         beq.s    .DMALoop1
  207.         move.w    $dff006,d1
  208. .DMALoop2    cmp.w    $dff006,d1
  209.         beq.s    .DMALoop2
  210.         move.w    $dff006,d1
  211.            dbf    d0,.DMALoop1
  212.         endm
  213.  
  214. ;------------------------------------------------------------------------------
  215. ;==                INIT                         ==
  216. ;------------------------------------------------------------------------------
  217. SFX_Init
  218.     ifne SFX__FastMode
  219.         lsr.l    #1,d0        ; Double playback rate
  220.     endc
  221.  
  222.         move.w    d0,SFX_PlayRate
  223.  
  224.         moveq.l    #0,d0
  225.         bsr.w    SFX_StopSound        ; Play no sound.
  226.  
  227.         moveq.l    #1,d0
  228.         bsr.w    SFX_StopSound        ; Play no sound.
  229.  
  230.         lea    SFX_AudioBuff,a0
  231.         move.w    #SFX__BuffSize-1,d1
  232. .ClrLoop    clr.w    (a0)+            ; Clear track buffers
  233.         dbf    d1,.ClrLoop
  234.  
  235.         clr.b    SFX_WhichBuffer        ; Buffer flag
  236.  
  237.     ifeq SFX__Mode
  238.         bsr.w    SFX_VBLInit
  239.     endc
  240.     ifeq SFX__Mode-1
  241.         bsr.w    SFX_AudIntInit
  242.     endc
  243.         beq.s    .Err
  244.  
  245.         moveq.l    #1,d0
  246.         rts
  247.  
  248. .Err        bsr.s    SFX_End
  249.         moveq    #0,d0
  250.         rts
  251.  
  252. ;------------------------------------------------------------------------------
  253. ;==                END                         ==
  254. ;------------------------------------------------------------------------------
  255. SFX_End
  256.     ifeq SFX__Mode
  257.         bsr.w    SFX_VBLEnd
  258.     endc
  259.     ifeq SFX__Mode-1
  260.         bsr.w    SFX_AudIntEnd
  261.     endc
  262.  
  263.         rts
  264.  
  265. ;------------------------------------------------------------------------------
  266. ;==                SETVOLUME                     ==
  267. ;------------------------------------------------------------------------------
  268. SFX_SetVolume    move.w    d0,$dff0d8
  269.         move.w    d0,SFX_Volume
  270.         rts
  271.  
  272. ;------------------------------------------------------------------------------
  273. ;==                STARTSOUND                     ==
  274. ;------------------------------------------------------------------------------
  275. SFX_StartSound    tst.l    d0
  276.         beq.s    .Zero
  277.  
  278.         lea    SFX_PartitionB,a2
  279.         move.l    a0,vd_StartPtr(a2)    ; Init ptr
  280.         move.l    a1,vd_EndPtr(a2)    ; Init endptr
  281.         move.l    #1,vd_Active(a2)
  282.  
  283.         rts
  284.  
  285. .Zero        lea    SFX_PartitionA,a2
  286.         move.l    a0,vd_StartPtr(a2)    ; Init ptr
  287.         move.l    a1,vd_EndPtr(a2)    ; Init endptr
  288.         move.l    #1,vd_Active(a2)
  289.  
  290.         rts
  291.  
  292. ;------------------------------------------------------------------------------
  293. ;==                STOPSOUND                     ==
  294. ;------------------------------------------------------------------------------
  295. SFX_StopSound    tst.l    d0
  296.         beq.s    .Zero
  297.  
  298.         lea    SFX_PartitionB,a2
  299.         move.l    #SFX_ZeroData,vd_StartPtr(a2)    ; Init startptr
  300.         move.l    #SFX_ZeroData+SFX__BuffSize,vd_EndPtr(a2); Init endptr
  301.         move.l    #0,vd_Active(a2)
  302.  
  303.         rts
  304.  
  305. .Zero        lea    SFX_PartitionA,a2
  306.         move.l    #SFX_ZeroData,vd_StartPtr(a2)    ; Init startptr
  307.         move.l    #SFX_ZeroData+SFX__BuffSize,vd_EndPtr(a2); Init endptr
  308.         move.l    #0,vd_Active(a2)
  309.  
  310.         rts
  311.  
  312.     ifeq SFX__Mode
  313.  
  314. ;------------------------------------------------------------------------------
  315. ;==                VBL INIT                     ==
  316. ;------------------------------------------------------------------------------
  317. SFX_VBLInit    lea    $dff000,a0
  318.  
  319.         move.w    #$0008,$96(a0)        ; dmacon (disable audio)
  320.         move.l    #$0400,$9a(a0)        ; intena (disable audio)
  321.  
  322.         move.w    #SFX__BuffSize/2,aud3+ac_len(a0); Buffer size
  323.         move.w    #65535,aud3+ac_per(a0)        ; Period
  324.         move.l    #SFX_AudioBuff,aud3+ac_ptr(a0)    ; Pointer
  325.         move.w    SFX_Volume,aud3+ac_vol(a0)    ; Volume
  326.  
  327.         SFX_WAITDMA
  328.  
  329.         move.w    #$8008,$96(a0)        ; dmacon (enable audio)
  330.  
  331.         moveq.l    #1,d0
  332.         rts
  333.  
  334. ;------------------------------------------------------------------------------
  335. ;==                VBL END                         ==
  336. ;------------------------------------------------------------------------------
  337. SFX_VBLEnd    move.w    #$0008,$dff096
  338.         rts
  339.  
  340. ;------------------------------------------------------------------------------
  341. ;==            VBL FRAMEHANDLER                     ==
  342. ;------------------------------------------------------------------------------
  343. SFX_VBLFrame    lea.l    SFX_AudioBuff,a1
  344.         not.b    SFX_WhichBuffer        ; Swap buffer
  345.         beq.s    .SetBuff
  346.  
  347. .UseBuff1    lea.l    SFX__BuffSize(a1),a1    ; Get next buffer
  348.  
  349. .SetBuff    lea.l    $dff000,a0
  350.  
  351.         move.w    #$0008,$96(a0)        ; dmacon (disable audio)
  352.  
  353.         move.w    #SFX__BuffSize/2,aud3+ac_len(a0); Buffer size
  354.         move.w    SFX_PlayRate,aud3+ac_per(a0)    ; Period
  355.         move.l    a1,aud3+ac_ptr(a0)        ; Pointer
  356.         move.w    SFX_Volume,aud3+ac_vol(a0)    ; Volume
  357.  
  358.         SFX_WAITDMA
  359.  
  360.         move.w    #$8008,$96(a0)        ; dmacon (enable audio)
  361.  
  362.         bsr.s    SFX_DoMix
  363.  
  364.         rts
  365.  
  366.     endc
  367.  
  368.     ifeq SFX__Mode-1
  369.  
  370. ;------------------------------------------------------------------------------
  371. ;==            AUDIOINTERRUPT INIT                     ==
  372. ;------------------------------------------------------------------------------
  373. SFX_AudIntInit    moveq    #10,d0            ; INTB_AUD3
  374.         lea    SFX_AudIntReq,a1
  375.         move.l    4.w,a6
  376.         jsr    -162(a6)        ; _LVOSetIntVector
  377.  
  378.         move.l    d0,SFX_PrevAudInt
  379.         beq.w    .Err
  380.  
  381.         lea    $dff000,a0
  382.         move.w    #SFX__BuffSize/2,$d4(a0); Buffer size
  383.         move.w    #65535,$d6(a0)        ; Period
  384.         move.l    #SFX_AudioBuff,$d0(a0)    ; Pointer
  385.         move.w    SFX_Volume,$d8(a0)    ; Volume
  386.  
  387.         lea    $dff000,a0
  388.         move.w    #$4000,$9a(a0)
  389.  
  390.         move.l    4.w,a6
  391.         jsr    -120(a6)        ; _LVODisable
  392.  
  393.         lea    $dff000,a0
  394.         move.w    #$0008,$96(a0)        ; Audio DMA off
  395.         move.w    #$8400,$9a(a0)        ; Enable sound interrupt
  396.         move.w    #$c000,$9a(a0)
  397.         move.w    #$8008,$96(a0)        ; DMA Audio channel 3 ON
  398.  
  399.         move.l    4.w,a6
  400.         jsr    -126(a6)        ; _LVOEnable
  401.  
  402.         moveq.l    #1,d0
  403.         rts
  404.  
  405. .Err        moveq.l    #0,d0
  406.         rts
  407.  
  408. ;------------------------------------------------------------------------------
  409. ;==            AUDIOINTERRUPT END                     ==
  410. ;------------------------------------------------------------------------------
  411. SFX_AudIntEnd    tst.b    SFX_IfPlay
  412.         beq.s    .NoPlay
  413.  
  414.         move.w    #1<<10,$dff09a
  415.         move.w    #$8,$dff096
  416.         clr.b    SFX_IfPlay
  417.  
  418. .NoPlay        move.l    SFX_PrevAudInt,d0
  419.         beq.s    .NoInt            ; Any interrupt?
  420.  
  421.         move.l    #0,SFX_PrevAudInt    ; Clear interrupt
  422.         move.w    #1<<10,$dff09a        ; intena
  423.         move.l    d0,a1
  424.         moveq    #10,d0
  425.         move.l    4.w,a6
  426.         jsr    -162(a6)        ; _LVOSetIntVector
  427.  
  428. .NoInt        move.w    #$0008,$dff096        ; Stop Audio DMA
  429.  
  430.         rts
  431.  
  432. ;------------------------------------------------------------------------------
  433. ;==                INTHANDLER                     ==
  434. ;------------------------------------------------------------------------------
  435. SFX_AudInt    movem.l    d2-a0/a2-a6,-(sp)
  436.  
  437.         not.b    SFX_WhichBuffer        ; Swap buffer
  438.         beq.s    .SetBuff
  439.  
  440. .UseBuff1    lea.l    SFX__BuffSize(a1),a1    ; Get next buffer
  441.  
  442. .SetBuff    lea.l    $dff000,a0
  443.         move.l    a1,$d0(a0)
  444.  
  445.          move.w    #SFX__BuffSize/2,$d4(a0); Buffer size
  446.         move.w    SFX_PlayRate,$d6(a0)    ; Period
  447.         move.w    SFX_Volume,$d8(a0)    ; Volume
  448.  
  449.         move.w    #1<<10,$9c(a0)        ; Clear intreq bit
  450.  
  451.         bsr.s    SFX_DoMix
  452.  
  453.         moveq.l    #0,d0
  454.  
  455.         movem.l    (sp)+,d2-a0/a2-a6
  456.         rts
  457.  
  458.     endc
  459.  
  460. ;------------------------------------------------------------------------------
  461. ;==                DOMIX                         ==
  462. ;------------------------------------------------------------------------------
  463. SFX_DoMix
  464.     ifne SFX__Debug
  465.         move.w    #$fff,$dff180
  466.     endc
  467.  
  468.         lea.l    SFX_PartitionA,a3
  469.  
  470.         tst.l    vd_Active(a3)        ; Addvalue
  471.         beq.s    .AOk
  472.  
  473.     ifeq SFX__FastMode
  474.         add.l    #SFX__BuffSize,vd_StartPtr(a3)    ; Next chunk
  475.         move.l    (a3),d7            ; Fetch ptr
  476.         add.l    #SFX__BuffSize,d7
  477.         cmp.l    vd_EndPtr(a3),d7    ; Will we break?
  478.         bls.s    .AOk
  479.     else
  480.         add.l    #SFX__BuffSize/2,vd_StartPtr(a3); Next chunk
  481.         move.l    (a3),d7            ; Fetch ptr
  482.         add.l    #SFX__BuffSize/2,d7
  483.         cmp.l    vd_EndPtr(a3),d7    ; Will we break?
  484.         bls.s    .AOk
  485.     endc
  486.  
  487.         clr.l    vd_Active(a3)        ; Stop sound
  488.         move.l    #SFX_ZeroData,vd_StartPtr(a3)
  489.         move.l    #SFX_ZeroData+SFX__BuffSize,vd_EndPtr(a3)
  490.  
  491. .AOk        lea.l    SFX_PartitionB,a4
  492.  
  493.         tst.l    vd_Active(a4)        ; Addvalue
  494.         beq.s    .BOk
  495.  
  496.     ifeq SFX__FastMode
  497.         add.l    #SFX__BuffSize,vd_StartPtr(a4)    ; Next chunk
  498.         move.l    (a4),d7            ; Fetch ptr
  499.         add.l    #SFX__BuffSize,d7
  500.         cmp.l    vd_EndPtr(a4),d7    ; Will we break?
  501.         bls.s    .BOk
  502.     else
  503.         add.l    #SFX__BuffSize/2,vd_StartPtr(a4)    ; Next chunk
  504.         move.l    (a4),d7            ; Fetch ptr
  505.         add.l    #SFX__BuffSize/2,d7
  506.         cmp.l    vd_EndPtr(a4),d7    ; Will we break?
  507.         bls.s    .BOk
  508.     endc
  509.  
  510.         clr.l    vd_Active(a4)        ; Stop sound
  511.         move.l    #SFX_ZeroData,vd_StartPtr(a4)
  512.         move.l    #SFX_ZeroData+SFX__BuffSize,vd_EndPtr(a4)
  513.  
  514. .BOk        move.l    vd_StartPtr(a3),a3    ; Get startaddress A
  515.         move.l    vd_StartPtr(a4),a4    ; Get startaddress B
  516.  
  517.     ifeq SFX__FastMode
  518.         move.l    #SFX__BuffSize-1,d5
  519.     else
  520.         move.l    #(SFX__BuffSize/2)-1,d5
  521.     endc
  522. .MixLoop
  523.  
  524.     ifeq SFX__FastMode
  525.         move.b    (a3)+,d4        ; Get sample 1
  526.         add.b    (a4)+,d4        ; Add sample 2
  527.         move.b    d4,(a1)+        ; Store value in buffer.
  528.     else
  529.         move.b    (a3)+,(a1)+        ; Get sample 1
  530.         move.b    (a4)+,(a1)+        ; Get sample 2
  531.     endc
  532.  
  533.         dbf    d5,.MixLoop
  534.  
  535.     ifne SFX__Debug
  536.         move.w    #0,$dff180
  537.     endc
  538.         rts
  539.  
  540. ;------------------------------------------------------------------------------
  541.  
  542. SFX_ZeroData    dcb.b    SFX__BuffSize,0
  543.     EVEN
  544.  
  545. SFX_PartitionA    dcb.b    vd_sizeof,0
  546. SFX_PartitionB    dcb.b    vd_sizeof,0
  547.  
  548.     ifeq SFX__Mode-1
  549.  
  550. SFX_AudIntReq    dc.l    0,0            ; SUCC, PRED
  551.         dc.b    2            ; NT_INTERRUPT
  552.         dc.b    0
  553.         dc.l    .IntName
  554.  
  555.         dc.l    SFX_AudioBuff
  556.         dc.l    SFX_AudInt,0
  557. .IntName    dc.b    "SoundFX audioint",0
  558.     EVEN
  559. SFX_PrevAudInt    dc.l    0
  560.  
  561.     endc
  562.  
  563. SFX_PlayRate    dc.w    0
  564. SFX_Volume    dc.w    64
  565. SFX_IfPlay    dc.b    0
  566. SFX_WhichBuffer    dc.b    0
  567.  
  568. SFX_AudioBuff    ds.b    SFX__BuffSize*2        ; Two buffers
  569.  
  570.